#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>

#include<sys/shm.h>
#include "my_shm_pubsub.h"
 
typedef union semun
{
	int val;
}semun;
 
int sem_init(int key);
 
void sem_p(int id,int sem);
 
void sem_v(int id,int sem);
 
void sem_del(int id);

int sem_init(int key)
{
	int semid;
	semid=semget((key_t)key,0,0666);
	if(semid==-1)
	{
		semid=semget((key_t)key,1,0666 | IPC_CREAT);
 
		semun mu;
		mu.val=1;
 
		semctl(semid,0,SETVAL,mu);
	}
	return semid;
}
 
void sem_p(int id,int sem)
{
	struct sembuf buff;
	buff.sem_num=sem;
	buff.sem_op=-1;
	buff.sem_flg=SEM_UNDO;
	semop(id,&buff,1);
}
 
void sem_v(int id,int sem)
{
	struct sembuf buff;
	buff.sem_num=sem;
	buff.sem_op=1;
	buff.sem_flg=SEM_UNDO;
	semop(id,&buff,1);
}
 
void sem_del(int id)
{
	semctl(id,0,IPC_RMID);
}

//因为共享内存中可能存在的竟态条件，因此共享内存需要和其他进程间通讯方式一起使用

typedef struct shm_test_a
{
    /* data */
    int index;
    int time;
    unsigned char data[1920*1080*3];
};


int main()
{
    #if 1
	int shmid=shmget((key_t)1234,1024*1024*10,0666 | IPC_CREAT);
	assert(shmid!=-1);
 
	char *ptra=(char *)shmat(shmid,NULL,0);    //共享内存被创建后，我们不能立即访问它，而是需要现将它从关联到进程的地址空间中分离
	assert(ptra!=(char *)-1);
 
	int semid=sem_init(123);
    int count = 0;
	while(1)
	{
		sem_p(semid,0);
		// printf("Put sentence:");
		// fflush(stdout);
 
		// memset(ptra,0,512);
		// fgets(ptra,128,stdin);
 
		// ptra[strlen(ptra)-1]=0;
 
		// if((strcmp(ptra,"end")==0) || (strcmp(ptra,"END")==0))
		// {
		// 	break;
		// }
        shm_test_a a = { 0 };
        a.index = count++;
        memcpy(ptra, &a, sizeof(a));
		sem_v(semid,0);
        usleep(30000);
	}
	shmdt(ptra);
    #else
    int count = 0;
    shm::publish::Publisher pub("mytest");
    while (1)
    {
        /* code */
        shm_test_a a = { 0 };
        a.index = count++;
        printf("index:%d\n", a.index);
        pub.publish((unsigned char*)&a, sizeof(a));
        usleep(30000);

    }
    #endif

	return 0;
}